Este projeto consiste em uma análise de dados históricos dos jogos olímpicos.
Utilize qualquer uma das bibliotecas estudadas (matplotlib, seaborn e plotly) para realizar as atividades propostas. Não há problema em usar apenas uma para realizar todas as atividades, nem em utilizar cada uma delas em uma atividade diferente - siga suas preferências pessoais!
Utilize os (muitos) parâmetros permitidos por cada função e/ou atributos dos objetos fornecidos pelas bibliotecas para criar uma identidade visual coesa para ser utilizada em todo o projeto. Use títulos, legendas e rótulos nos eixos para deixar os gráficos verdadeiramente informativos. E não se esqueça que a simples escolha das cores a serem utilizadas pode tornar os gráficos ainda mais interessantes!
O arquivo athlete_events.csv contém 271116 linhas e 15 colunas. Cada linha corresponde a um indivíduo (atleta) que competiu em um evento olímpico individual. Veja a descrição das 15 colunas, a seguir:
import streamlit as st
import pandas as pd
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import plotly.express as px
import seaborn as sns
import squarify
2022-02-22 21:05:25.028 INFO numexpr.utils: NumExpr defaulting to 4 threads.
df = pd.read_csv('./data/athlete_events.csv')
df.head()
| ID | Name | Sex | Age | Height | Weight | Team | NOC | Games | Year | Season | City | Sport | Event | Medal | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | A Dijiang | M | 24.0 | 180.0 | 80.0 | China | CHN | 1992 Summer | 1992 | Summer | Barcelona | Basketball | Basketball Men's Basketball | NaN |
| 1 | 2 | A Lamusi | M | 23.0 | 170.0 | 60.0 | China | CHN | 2012 Summer | 2012 | Summer | London | Judo | Judo Men's Extra-Lightweight | NaN |
| 2 | 3 | Gunnar Nielsen Aaby | M | 24.0 | NaN | NaN | Denmark | DEN | 1920 Summer | 1920 | Summer | Antwerpen | Football | Football Men's Football | NaN |
| 3 | 4 | Edgar Lindenau Aabye | M | 34.0 | NaN | NaN | Denmark/Sweden | DEN | 1900 Summer | 1900 | Summer | Paris | Tug-Of-War | Tug-Of-War Men's Tug-Of-War | Gold |
| 4 | 5 | Christine Jacoba Aaftink | F | 21.0 | 185.0 | 82.0 | Netherlands | NED | 1988 Winter | 1988 | Winter | Calgary | Speed Skating | Speed Skating Women's 500 metres | NaN |
1. Crie um DataFrame contendo apenas informações sobre atletas brasileiros. Exiba a quantidade de linhas desse novo DataFrame.
df_BRA = df[df['NOC'] == 'BRA']
linhas = df_BRA.shape[0]
print(f'Existem {linhas} linhas para atletas brasileiros')
Existem 3848 linhas para atletas brasileiros
2. Será que existe alguma correlação entre a altura do atleta e seu desempenho, para algum esporte? Faça essa análise separadamente para cada gênero, e conclua.
Gere um ou mais gráficos de sua escolha, em que seja possível comparar as alturas dos atletas de cada esporte, separando-os por gênero. Se necessário, crie colunas ou DataFrames auxiliares.
Facilitador: se quiser, analise apenas os esportes em que se tenha ao menos 5 atletas medalhistas e 5 atletas não medalhistas, para facilitar visualizações e conclusões.
#altura = df_BRA[['Height']].fillna(df_BRA['Height'].sum()/df_BRA.shape[0]) #Criando variável "altura para receber os valores NaN trocados por zero
#df_BRA.drop(['Height'], axis=1, inplace=True) #Excluindo coluna "Height" da base original ainda com valores NaN
#df_BRA.insert(4, 'Height', altura) #Inserindo nova coluna "Height" com os valores NaN alterados no DataFrame
#Selecionando os esportes que possuem pelo menos 5 medalhas
df_BRA_medal = df_BRA.groupby(by=['Sport', 'Sex'])['Medal'].value_counts()
df_BRA_medal = df_BRA_medal.to_frame(name='Total Medals')
df_BRA_medal = df_BRA_medal.reset_index()
df_BRA_medal = df_BRA_medal.groupby(by=['Sport', 'Sex'])['Total Medals'].sum()
df_BRA_medal = df_BRA_medal.to_frame(name='Total Medals')>5
df_BRA_medal = df_BRA_medal.reset_index()
df_BRA_medal = df_BRA_medal[df_BRA_medal['Total Medals'] == True]
lista_esporte_5medal = df_BRA_medal['Sport']
lista_esporte_5medal = lista_esporte_5medal.unique()
df_BRA_5medal = df_BRA[df_BRA['Sport'].isin(lista_esporte_5medal)]
df_aux = df_BRA_5medal.copy()
df_aux["Medal"].fillna("NoMedal", inplace=True) #Substituindo NaN por NoMedal
df_male = pd.DataFrame(df_aux[df_aux['Sex'] == 'M']) #Criando dataframe masculino
df_female = pd.DataFrame(df_aux[df_aux['Sex'] == 'F']) #Criando dataframe feminino
df_female_medals = df_female[df_female["Medal"].isin(["Silver","Gold","Bronze"])] #Dataframe de medalhistas feminino
df_male_medals = df_male[df_male["Medal"].isin(["Silver","Gold","Bronze"])] #Dataframe de medalhistas masculino
df_female_nomedals = df_female[df_female["Medal"].isin(["NoMedal"])] #Dataframe de não medalhistas feminino
df_male_nomedals = df_male[df_male["Medal"].isin(["NoMedal"])] #Dataframe de não medalhistas masculino
#Criando dataframe com a média das alturas dos medalhistas
df_medal = pd.DataFrame(df_BRA_5medal.loc[df_BRA['Medal'].notnull()])
df_medal = round(df_medal.groupby(by=['Sport', 'Sex'])['Height'].mean(), 2) #Criando média de altura de medalhistas por esporte
df_medal = df_medal.to_frame(name='Average height')
df_medal = df_medal.reset_index()
#Criando dataframe com a média das alturas dos NÃO medalhistas
df_non_medals = pd.DataFrame(df_BRA_5medal.loc[df_BRA['Medal'].isna()]) #Criando dataframe com as colunas desejadas com as NÃO medalhistas
df_non_medals = round(df_non_medals.groupby(by=['Sport', 'Sex'])['Height'].mean(), 2) #Criando média de altura de medalhistas por esporte
df_non_medals = df_non_medals.to_frame(name='Average height')
df_non_medals = df_non_medals.reset_index()
#Unindo as duas tabelas (média das alturas dos medalhistas e dos não medalhistas)
df_height_medal = pd.merge(left=df_medal, right=df_non_medals, on=['Sport', 'Sex'], how='outer', suffixes=('_medal', '_nomedal'))
#DataFrame com a contagem de medalhas
sport_medal_height = df_BRA_5medal.groupby(by=['Sport','Height','Sex'])['Medal'].count()
df_sport_medal_height = sport_medal_height.reset_index()
legenda = {'Average height_medal' : 'Com medalha',
'Average height_nomedal' : 'Sem medalha',
}
fig1 = px.bar(df_height_medal[df_height_medal['Sex'] == 'F'],
x='Sport',
y=['Average height_medal', 'Average height_nomedal'],
barmode='group',
color_discrete_sequence=px.colors.sequential.Magenta,
template='plotly_white',
width= 920,
height=480)
fig1.update_layout(title={'text': 'Média das alturas das mulheres por esporte',
'y':0.9,
'x':0.4,
'xanchor': 'center',
'yanchor': 'top'},
xaxis_title="Esporte",
yaxis_title="Média das alturas",
legend_title="Medalhas",
font_family="Arial",
font_color="gray",
title_font_color="gray",
legend_title_font_color="gray",
)
fig1.for_each_trace(lambda t: t.update(name = legenda[t.name],
legendgroup = legenda[t.name],
hovertemplate = t.hovertemplate.replace(t.name, legenda[t.name])
)
)
fig1.show()
fig2 = px.bar(df_height_medal[df_height_medal['Sex'] == 'M'],
x='Sport',
y=['Average height_medal', 'Average height_nomedal'],
barmode='group',
color_discrete_sequence=px.colors.sequential.Aggrnyl,
template='plotly_white',
width= 920,
height=480)
fig2.update_layout(title={'text': 'Média das alturas dos homens por esporte',
'y':0.9,
'x':0.4,
'xanchor': 'center',
'yanchor': 'top'},
xaxis_title="Esporte",
yaxis_title="Média das alturas",
legend_title="Medalhas",
font_family="Arial",
font_color="gray",
#title_font_family="Times New Roman",
title_font_color="gray",
legend_title_font_color="gray",
)
fig2.for_each_trace(lambda t: t.update(name = legenda[t.name],
legendgroup = legenda[t.name],
hovertemplate = t.hovertemplate.replace(t.name, legenda[t.name])
)
)
fig2.show()
df_volley_female = df_sport_medal_height[(df_sport_medal_height['Sport'] == 'Volleyball') &
(df_sport_medal_height['Sex'] == 'F')]
sns.set_palette("pastel")
fig3, ax = plt.subplots()
ax = sns.kdeplot(df_volley_female[df_volley_female['Medal']==0]['Height'], label = "Sem medalhas")
ax = sns.kdeplot(df_volley_female[df_volley_female['Medal']!=0]['Height'], label = "Com medalhas")
ax.legend(title = 'Medalhas femininas')
plt.xlabel('Distribuição de alturas')
plt.ylabel('Probabilidade de densidade')
plt.show()
df_volley_male = df_sport_medal_height[(df_sport_medal_height['Sport'] == 'Volleyball') &
(df_sport_medal_height['Sex'] == 'M')]
fig4, ax1 = plt.subplots()
ax1 = sns.kdeplot(df_volley_male[df_volley_male['Medal']==0]['Height'], label = "Sem medalhas")
ax1 = sns.kdeplot(df_volley_male[df_volley_male['Medal']!=0]['Height'], label = "Com medalhas")
ax1.legend(title = 'Medalhas masculinas')
plt.xlabel('Distribuição de alturas')
plt.ylabel('Probabilidade de densidade')
plt.show()
3. Vamos analisar agora as medalhas que nossos atletas trouxeram para casa.
Crie uma visualização de sua preferência para mostrar, por esporte, a proporção de medalhas de ouro, prata e bronze que nosso país já consquistou.
Facilitador: Se preferir, mostre as proporções apenas para os 6 esportes que tiveram mais medalhas.
DICA: Cuidado! Esportes em equipe dão medalhas a todos os jogadores, mas só contabilizam uma vez!
#DF contendo as medalhas por esporte após retirar as medalhas repetidas dos esportes coletivos (mais de um jogador ganha a medalha pelo mesmo evento)
df_dropado = df_BRA[["Games", "Sport", "Event", "Medal"]].drop_duplicates()
df_get = pd.get_dummies(df_dropado, columns = ['Medal'])
df_get_2 = pd.pivot_table(df_get, values=['Medal_Bronze', "Medal_Silver", "Medal_Gold"], index=['Sport'], #margins = True,
aggfunc={'Medal_Bronze': np.sum,
'Medal_Silver': np.sum,
'Medal_Gold': np.sum,
}).reset_index()
df_get_2['Medal_Bronze %'] = df_get_2['Medal_Bronze']/df_get_2['Medal_Bronze'].sum()
df_get_2['Medal_Silver %'] = df_get_2['Medal_Silver']/df_get_2['Medal_Silver'].sum()
df_get_2['Medal_Gold %'] = df_get_2['Medal_Gold']/df_get_2['Medal_Gold'].sum()
df_get_2['Medal_Bronze %'] = round(df_get_2['Medal_Bronze']/df_get_2['Medal_Bronze'].sum() * 100)
df_get_2['Medal_Silver %'] = round(df_get_2['Medal_Silver']/df_get_2['Medal_Silver'].sum() * 100)
df_get_2['Medal_Gold %'] = round(df_get_2['Medal_Gold']/df_get_2['Medal_Gold'].sum() * 100)
df_medal_proportion = df_get_2[(df_get_2['Medal_Bronze']+df_get_2['Medal_Gold']+df_get_2['Medal_Silver'])>5]
df_medal_bronze_proportion_ord = df_medal_proportion.sort_values(by=['Medal_Bronze %'])
df_medal_silver_proportion_ord = df_medal_proportion.sort_values(by=['Medal_Silver %'])
df_medal_gold_proportion_ord = df_medal_proportion.sort_values(by=['Medal_Gold %'])
list_medal = ['Medal_Bronze %', 'Medal_Silver %', 'Medal_Gold %']
df_medal_proportion.groupby(by='Sport')[list_medal].sum()
| Medal_Bronze % | Medal_Silver % | Medal_Gold % | |
|---|---|---|---|
| Sport | |||
| Athletics | 13.0 | 8.0 | 17.0 |
| Beach Volleyball | 5.0 | 19.0 | 10.0 |
| Football | 3.0 | 14.0 | 3.0 |
| Judo | 24.0 | 8.0 | 13.0 |
| Sailing | 13.0 | 8.0 | 23.0 |
| Swimming | 15.0 | 11.0 | 3.0 |
| Volleyball | 3.0 | 8.0 | 17.0 |
fig5 = px.pie(df_medal_bronze_proportion_ord[df_medal_bronze_proportion_ord["Medal_Bronze %"]!=0],
names="Sport",
values="Medal_Bronze %",
title="Proporção de medalhas de Bronze do Brasil nas Olimpíadas",
#labels = labels,
width = 600,
height = 500,
color_discrete_sequence=px.colors.sequential.Oryel)
fig5.update_layout(title_x=0.50,
legend_title="Esportes",
)
# legenda4 = {'Judo' : 'Judô',
# 'Swimming' : 'Natação',
# 'Athletics' : 'Atletismo',
# 'Sailing' : 'Navegação',
# 'Beach Volleyball' : 'Vôlei de praia',
# 'Football' : 'Futebol',
# 'Volleyball' : 'Vôlei'
# }
# fig5.for_each_trace(lambda t: t.update(name = legenda4[t.name],
# legendgroup = legenda4[t.name],
# hovertemplate = t.hovertemplate.replace(t.name, legenda4[t.name])
# )
# )
fig5.show()
fig6 = px.pie(df_medal_silver_proportion_ord[df_medal_silver_proportion_ord["Medal_Silver %"]!=0],
names="Sport",
values="Medal_Silver %",
title="Proporção de medalhas de Prata do Brasil nas Olimpíadas",
#labels = labels,
width = 600,
height = 500,
color_discrete_sequence=px.colors.sequential.Greys)
fig6.show()
fig7 = px.pie(df_medal_gold_proportion_ord[df_medal_gold_proportion_ord["Medal_Silver %"]!=0],
names="Sport", values="Medal_Gold %",
title="Proporção de medalhas de Ouro nas Olimpiadas",
#labels = labels,
width = 600,
height = 500,
color_discrete_sequence=px.colors.sequential.turbid)
fig7.show()
4. Para finalizar a história do Brasil, vamos ver a série temporal de medalhas brasileiras.
Crie um gráfico de sua escolha, que mostre o total de medalhas de ouro, prata e bronze, por edição da olimpíada (em ordem cronológica).
DICA: Mais uma vez, tome cuidado com os esportes em grupo - os contabilize apenas uma vez!
df_get_3 = pd.pivot_table(df_get, values=['Medal_Bronze', "Medal_Silver", "Medal_Gold"], index=['Games'],
aggfunc={'Medal_Bronze': np.sum,
'Medal_Silver': np.sum,
'Medal_Gold': np.sum
}).reset_index()
fig8 = px.area(df_get_3[(df_get_3['Medal_Bronze']!=0) | (df_get_3['Medal_Silver']!=0) | (df_get_3['Medal_Gold']!=0)],
x='Games',
y=['Medal_Bronze','Medal_Silver','Medal_Gold'],
#color='Medals',
color_discrete_sequence=px.colors.sequential.Redor,
title='Medalhas por olimpíadas',
template='plotly_white',
width= 1000,
height=600)
fig8.update_layout(title={'y':0.85,
'x':0.45,
'xanchor': 'center',
'yanchor': 'top'},
xaxis_title="Olimpíadas",
yaxis_title="Número de medalhas",
legend_title="Medalhas",
font_family="Arial",
font_color="gray",
title_font_color="gray",
legend_title_font_color="gray",
)
legenda2 = {'Medal_Bronze' : 'Medalha de Bronze',
'Medal_Silver' : 'Medalha de Prata',
'Medal_Gold' : 'Medalha de Ouro'
}
fig8.for_each_trace(lambda t: t.update(name = legenda2[t.name],
legendgroup = legenda2[t.name],
hovertemplate = t.hovertemplate.replace(t.name, legenda2[t.name])
)
)
fig8.show()
5. Agora é com vocês!
Escolha uma análise visual que julga interessante de fazer neste conjunto de dados, faça o(s) gráficos(s) necessários e comente os resultados.
#10 maiores medalhistas de todos os tempos
df_name_medal = df.groupby(by=['Name', 'Sport'])['Medal'].count().reset_index()
df_name_medal.nlargest(10,'Medal')
| Name | Sport | Medal | |
|---|---|---|---|
| 87965 | Michael Fred Phelps, II | Swimming | 28 |
| 74150 | Larysa Semenivna Latynina (Diriy-) | Gymnastics | 18 |
| 95032 | Nikolay Yefimovich Andrianov | Gymnastics | 15 |
| 16391 | Borys Anfiyanovych Shakhlin | Gymnastics | 13 |
| 29842 | Edoardo Mangiarotti | Fencing | 13 |
| 96448 | Ole Einar Bjrndalen | Biathlon | 13 |
| 120310 | Takashi Ono | Gymnastics | 13 |
| 4028 | Aleksey Yuryevich Nemov | Gymnastics | 12 |
| 15562 | Birgit Fischer-Schmidt | Canoeing | 12 |
| 25178 | Dara Grace Torres (-Hoffman, -Minas) | Swimming | 12 |
fig9 = px.bar(data_frame = df_name_medal.nlargest(10,'Medal'),
x = 'Name',
y = 'Medal',
color = 'Sport',
template='plotly_white',
color_discrete_sequence=px.colors.sequential.Electric,
title = 'Maiores medalhistas olímpicos',
width= 920,
height=500)
fig9.update_layout(title={'y':0.85,
'x':0.45,
'xanchor': 'center',
'yanchor': 'top'},
# xaxis_visible=False,
#xaxis_showticklabels=False,
xaxis_title="",
yaxis_title="Número de medalhas",
legend_title="Esportes",
font_family="Arial",
font_color="gray",
title_font_color="gray",
legend_title_font_color="gray",
)
legenda3 = {'Swimming' : 'Natação',
'Gymnastics' : 'Ginástica olímpica',
'Fencing' : 'Esgrima',
'Biathlon' : 'Biatlo',
'Canoeing' : 'Canoagem'
}
fig9.for_each_trace(lambda t: t.update(name = legenda3[t.name],
legendgroup = legenda3[t.name],
hovertemplate = t.hovertemplate.replace(t.name, legenda3[t.name])
)
)
fig9.show()